=================== How E-Show MIDI Toys works....

Let's consider the three basic elements to a MIDI network, the controller, the
cable, and the controlled objects (the PC, Cable, and Objects.) Sometimes the
controller is a keyboard and other times it is a computer or PC. The controller
sends messages to the objects attached to it by the cable or cables. Any
controller can have 1 or more MIDI cable attachment points, physical ports.
Controlled objects generally have only one input; but, this is not necessarily
a requirement. The typical PC Show Control software may have multiple inputs
so that it can receive data from multiple objects via multiple cables. It is
noteworthy that MIDI mergers exist to merge any return messages from objects
to the controller. So a controller may have messages being received via cables
physically attached to it that are fed by MIDI mergers.

Each cable (or in/out cable pair) carries a MIDI universe of data. Each object
in a universe must have its own address. Consider this to be somewhat similar
in concept to the "universes" of the competing satellite TV networks, the local
cable TV universe, and the over the air broadcast TV universe. Each station has
an address, channel, in its given universe. Normally this metaphore breaks down
because it is one way only and a given "object" or "station" may appear on each
of the competing universes, often at different addresses. As we can see later
NetMIDI supporting controllers and objects can give you an effective matrix
function allowing an object to appear on multiple controllers or a controller
to appear in multiple universes in a matrix function. But the address for the
controller or object cannot be different in the different universes.

Each cable connector on a controller is in turn controlled by a device driver,
often referred to simply as a "device". Each device generally speaks to only
one MIDI universe. (Again note that the MIDI matrix capability in NetMIDI is
the chief exception here.) Within each universe we have the MIDI channels for
messages such as MIDI notes and program changes. We also have the MSC ID for
the more complex MIDI messages within a given universe.

Existing E-Show tools exist as individual universes per device entry as one
might expect. Many E-Show tools, however, can only have one object of any
sort attached to them even though they speak MSC. This one device, which then
speaks to one universe, connecting to only one controlled object is limiting.
But it is the typical E-Show tool paradigm. This can make E-Show tools easier
to configure. But it also limits the number of E-Show tools a PC can support.

E-Show 2 makes an attempt to break out of this mold with a two level approach.
You still specify the universes you want. Two types of universes exist. On
some, which simply provide alternate transport mechanisms with no translations,
this is all that gets specified. NetMIDI is an example of an alternate transport
mechanism. These work for all MIDI messages. On others you can specify multiple
MSC IDs for different kinds of exotic objects, PLCs, DMX translators, serial
ports, and so forth. With E-Show 2 you can define one universe that contains 
many controlled objects with each object being one of a menu of different type
of exotic objects. Of course, multiple devices of this sort can be created. And
in fact E-Show 1 can be perfectly emulated with the E-Show2 tool with each
exotic object having its own one object device controlling its own private
universe.

Thus E-Show 2 has a two step configuration process. The first defines the
"device" universes which will be present and the second, when appropriate,
defines objects attached to a given universe. This considerably increases the
number of distinct objects a Windows XP based computer can control. And E-Show3
achieves this with one single install of one single DLL.

(A planned enhancement of E-Show2 is dynamic configuration of the ports in a
universe from the controlling program via a control port. This is not present
in the first implementations of E-Show2 and won't be present until there is a
real identified demand for it.)

=======================

With the above description in mind the internal implementation of E-Show2 will
feature an individual class for each of the different types of exotic objects
it controlls. Each object or each universe, as appropriate, will have its own
instance as a means of keeping data distinct.

We'll need some means of preventing universe collisions, however. That means
we will have a class per universe. And that class, if appropriate, will in
turn own its complement of object classes.


== Configuration --

Configuration will have a panel defining the universes that will be present
and their names. Universes will number from 0 to N in sequence - CArray style.

Universe name, type of universe. Type of universe is NetMIDI, SerialMIDI, or
Translated. Edit box for name and pull down for type, list for universes.

Translated universes will have an MSC ID to Translation Type panel done with
pull downs and a list box. This will pop up the translation panel if any
additional information custom to the translation is needed.

= Main panel
Defined universes
	Single click loads description and type
	Double click is same as click then change button.
		(Universe configuration panel.)
	- So what do we store for each universe?
		class pointer for its instance
		name for MIDI report
		List for its object classes.	// Always at least one object before
										// a universe will "show" in getdev.
	- So what do we need for each translator/driver?
		class pointer for its instance.
		class pointer to its universe?
		pointer to its data pool.
		MSCID

Note that Universes must be defined "off line". Translation type Universe
properties may be altered online to match what is expected by the program. A
special SysEx addressed to the port handles this. It'll be the same SysEx for
all translation types. So this must be picked carefully. It will also support
a "query" as well as a "set". As a piece of the data we'll have a name to go
with the MSC ID.

MSC IDs or wire characteristics can be fiddled with directly.

Configure Universes
	Define or select a universe.
	Double click on it or click "change" without changing the description or
	type.

Configure a Universe
	Select a object and change or doubleclick an object or select an object
	type and "add".
		MSCID
		TYPE
		class pointer
		...

Individual configurations for each tool type.

Individual registry setting for each tool type.

Need tool for handling registry generic and specific. E-Show tools is a
good reference for this. But - now, how do I handle the dispatch and
"subclass?" Each subclass item has a logical ID that is used for addressing
it. Thus I can dispatch to a universe via an array with the ID taken as the
subclass.

We can store the universe information in an array of 32 possible devices.
Given the way we work that should be adequate. If I leave it a CArray it
is even easier to work with.

Do I perhaps have the MidiToys2Base handle the multiple universes? That
does sound reasonable - almost. But I think a MIDI_Universe class MIGHT be
called for. Let's look into this.... The Universe dispatches to the
Translators for the Translator type. It dispatches directly to the singular
translator for NetMIDI?

Xlators store their own data in internal arrays.

// 7,7 233, 223 List Window size in dialog

Each universe must have at least one object in it, either one alternate
transport or one or more translator tools but not both.

WaitForMultipleObjects MAXIMUM_WAIT_OBJECTS

Now we need to define what is the minimum amount of data to make a class.
Is this merely a Description with a -1 type as a place holder? Can MIDI
tools handle this? I think so if WE handle it correctly.

TODO next - (Not necessarily in order.)
a) Setup the Ethernet Translator as a translator object example.
b) Hook up the MTS232 object as well.

If we are going to do an Ethernet translator let's define the message
it takes. That requires snarbling off to look at some of the other
sysex using tools.... 

MIDI Syscommand:
USAGE NOTES:

	All messages are manufacturer sysex messages, and start with a
	pretty standard set of values:

	F0 00 00 40 id dd ss cc  ll ll tt tt ww ww hh hh wd 00 00 text F7
	 0  1  2  3  4  5  6  7   8  9 10 11 12 13 14 15 16 17 18   19 20

		id = doscue device type = 0x11
		dd = destination unit number
		ss = sender id
		cc = command
				01 = GO
				02 = STOP (unused)
				08 = all_off
				0A = reset

	Remaining parameters only present on GO

		ll ll	left window position (7F7F = don't use)
		tt tt	top window position	 (7F7F = don't use)
		ww ww	window width		 (7F7F = don't use)
		hh hh	window height		 (7F7F = don't use)
		wd		window display flag
				0 = SW_SHOWNORMAL,
				1 = SW_HIDE,
				2 = SW_SHOWMINIMIZED,
				3 = SW_SHOWMAXIMIZED,
				4..7F = reserved

		<title>  00		null terminated window title
		<curdir> 00		null terminated current directory
		<text>			the command text, possibly multiple lines
		F7				end of message

MIDI Ethernet would come out


			F0  00 00 40  17  dd  ss   ff ll ll ll  <data> F7
			 0   1  2  3   4   5   6    7  8  9 10

			00 00 40	= RSD manuf ID
			17			= MIDI_Ethernet device class (23)
			dd			= MIDI_Ethernet box address, 00..127 (set with jumpers)
			ss			= MIDI Source address
			ff			=> 40 == ASCII, 41 == nybbles, 42 == Base64
			llllll		= 3 bytes of length following this not including the F7

	nybble encoding: standard hex alpha notation for digits 0..9 and letters
	a..f. Uppercase A..F is equivalent to lower case.
	Base64 encoding is Internet standard Base64 encoding.

llllll bytes of data are sent out the Internet port as a TCP stream. Nagling
is turned off so that short packets (under 1400 bytes or so) go out as a
single packet.

Need to know data:
1)	Client/Server/MultiServer/UDP ?
2)	Correspondent address (0 for server if wild cards accepted.)
3)	Direction
4)	MSC ID to which this Ethernet port responds.

Configuration done for EthernetMIDI and NetMIDI. So both paths work. Now to
investigate the concept of each "device" having a SysEx for querying defined
port objects on that device plus an additional one for all devices.

Query This Device Index					2 nybbles device index.
Query Port Numbers Active				128 bits of data as nybbles.
Query Port Type and Name				2 bytes type & null terminated string

Query Enum EShow2 Devices				2 nybbles device index.
Query EShow2 Device	Active	<index>		128 bits of data as nybbles.
Query EShow2 Device Port	<index><port>
										2 bytes type & null terminated string

So these will be interpreted at the BASE level with the answers pulled
down from above and dispatched as per MAD2 dispatch.

Status here:
NetMIDI and EthernetMIDI configuration is done correctly.
GetNumDevs is done. Note that ALL devices are input and output together.
GetDevCaps is also perhaps done.

NOTE: There is one class instance for each device that shows up in the
MIDI device enumeration. This follows the MTS232V2 implementation model.
Basically there is only one open per class even for translators. The
"pending ports" are the tools for handling messages with multiple IDs
when different physical transports are involved. (Different ethernet
destination addresses, different COM ports, etc.)

I may have a problem..... The configuration is setup as if each universe had
its own master one master MidiDataDriver and called the subdrivers as needed.
So there is only port data data structure that would have to be dealt with in
any given data driver. And it already has the MSCID tested. So it really may
have very little to do.

TODO
@)D		May be able to install and test the silly thing for configuration
		and device list in MidiWire or the like.

a)		Generate the base level message handlers since everything has that
		code as its entry points to the E-Show2 handlers.
D		DriverProc() is "done".
D		Now for basic midm and modm handlers.

b)		Get the first three of the above Query SysEx messages done.

c)		Hook up the Richmond StatLink on all pages.

d)		Ethernet driver additions
D		a) Memory leak sending messages.	(Phew!)
		b) Add MTS232 nybbles - 70-7f to the Ethernet formats.
		c) Add SOME way to ignore the last message sent when it comes back in.
D		d) Change to use "MM_RSD_MIDI_ETHERNET" instead of "MM_RSD_MIDI_ESHOW2"
		   packet format ID byte - duh!
D		e) Change system so that the MIDI close command closes and deletes the
		   translator classes. That should solve most of the problems.
		f) Now make TCP work, too.


Seems I cannot share hDev between send and receive - sort of a "duh" thing for
UDP. So I need to tweak usages.


NETMIDI NOTES
                     About NetMIDI
NetMIDI creates input MIDI ports that can receive data from output 
ports on this computer and output ports on any other computer in 
the same domain as this computer.  NetMIDI also creates output MIDI 
ports that can send data to one or more NetMIDI input ports on this 
computer or any other computer in the domain.

A NetMIDI output port can send to multiple input ports on multiple 
computers.  Likewise, a NetMIDI input port can receive data from 
multiple NetMIDI output ports.  You can think of NetMIDI as a 
combination of a MIDI Thru and a MIDI Merger that also works across 
multiple computers.

NetMIDI is most commonly used with ShowMan and other show control 
systems, however it will also work to distribute normal musical MIDI 
data.  To keep from getting MIDI data from multiple shows confused, 
NetMIDI has the concept of Shows.  Each NetMIDI input or output port 
belongs to a single Show.  Only other ports belonging to the same 
Show can share data.  Another NetMIDI port on the same computer (or 
the same computer network) that has a different Show name is 
completely separate and will not share any data with the first group 
of ports.  This lets you distribute data for multiple shows over the 
same computer network without fear of the show data becoming confused.

NetMIDI has "virtual MIDI cables" called Groups.  Any NetMIDI output 
port can send to one or more Groups.  This is exactly the same as 
using a Thru box to drive multiple MIDI cables from the same device 
output.  Also, any NetMIDI input can receive data from one or more 
groups.  This is exactly like using a Merge box to combine the data 
on multiple MIDI cables to a single MIDI input.

How you use Groups is up to you.  However, every output and every 
input must be assigned to at least one Group.  A NetMIDI input port 
assigned to Group 1 can only receive data from NetMIDI output ports 
assigned to Group 1.  Of course you can assign more than one Group 
number to any input or output.  But remember that each Group is a 
separate "MIDI cable", and you have to connect both ends of the 
same cable to have the data get from here to there.

         To create a new NetMIDI port:
Fill in a unique description.  Either select the desired Show name 
from the dropdown list, or type the name of a new Show into the list 
window.  Remember that spelling and case counts!  If the show names on 
the sending and receiving systems are not spelled identically, they are 
different shows and the data will not get from there to here.  
Next select the desired port direction, Input (receive) or Output 
(send).  Select the groups that you want to use for this port.  
Any port must be assigned to at least one group. Then Click on Add.

When setting up the sending and receiving ports for ShowMan or any 
other device, remember that if you assign both the sending and 
receiving ports to the same Group you will create a Loopback device.  
This is generally not desirable as it will result in MIDI feedback.  
ShowMan has an internal Loopback device that can be used when it is 
needed.

         To modify an existing NetMIDI port:
Click on the port you want to modify in either the Sending or 
Receiving listbox at the 
top of the window.  This will load the current parameters into the 
controls at the bottom.  Modify the desired parameters, then click 
on the Change button.
         To delete an existing NetMIDI port:
Click on the port you want to modify in either the Sending or 
Receiving listbox at the 
top of the window.  This will load the current parameters into the 
controls at the bottom.  Click the Delete button.
         To select UDP or the new TCP mode:
Click on the UDP/TCP box to change mode. UDP is the old broadcast 
mode. TCP is a new point to point 'reliable' mode. Note that only 
one each MIDI input and output may be configured if using TCP mode.
         To select correspondant address in TCP mode:
Click on the TCP Address box. Enter the dotted address, either as 
foo.bar.baz or dotted quads, 10.20.30.40. This is not needed in UDP 
mode; but, it must be present in TCP mode. Both ends of the connection 
must be set to each other's address for this to work.
Note that TCP mode has a lamentable tendancy to coalesce packets. 
This may lead to receiving garbage. If you experience this please 
notify RSD immediately.
                            NOTES:
All changes can be discarded by clicking on the Cancel button.
No changes are actually made until clicking on the OK button.
If a port is open when it is changed or deleted, the changes
will not take effect for that port until the port is closed and
reopened.



Behavior of Review and Demo bits.

Open with a license splash screen - make it the basic help panel.
Have it stay up for awhile then go away - probably as part of another
thread?


Review is simple. When the review period is over the Demo behavior
begins.

Demo splash notes that only the first run saves any edited ports data.
Subsequent runs MAY degrade performance - fetch a true random number
and if this is one run in sixteen delay each message by 30 ms. (On the
10th message pop-up a message.)


TODO:	DosCommand partially broken.... The second try trick does not
append properly. Go to the wide version of the command.


Driving the new DosCommand

For normal files simply use it as before.

For the message window facility the command syntax is:

[setfont ["]name["],NNN] [delay MMMM] @DOSMESSAGE@ [/C] [/W] "message line" ["additional line"]

NNN is the delay in milliseconds (or seconds if less than 100).
MMMM is the font size. 250 is a reasonable size! 20 is microprint.
/C	means center the text in the dialog
/M  means maximize the control.

setfont "Arial",150 delay 5000 @DOSMESSAGE@ /C " " "Please Stand By" " " "LOADING WATERWORLD SHOW" " " "PROGRAMMING BY J.C.W. PRODUCTIONS INC." "AMIGA TO WINDOWS CONVERSION BY LOREN WILTON"


Now need to modify the freaking thing to use pMPorts rather than PClients in the
callbacks. This may prove "annoying." But I hope it won't be TOO bad. Having some
tools to test with helps.

